package com.leo.tool.jdk.core;

import lombok.SneakyThrows;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {

    ReentrantLock lock = new ReentrantLock();

    int count = 0;

    @Before
    public void setUp() {
        count = 0;
    }

    @SneakyThrows
    @Test
    public void testLock() {
        Thread thread1 = new Thread(this::lock);
        Thread thread2 = new Thread(this::lock);
        thread1.start();
        thread2.start();    // Thread state change to WAIT
        thread1.join();
        thread2.join();
        Assert.assertEquals(2, count);
    }

    @SneakyThrows
    @Test
    public void testTryLock() {
        Thread thread1 = new Thread(this::tryLock);
        Thread thread2 = new Thread(this::tryLock);
        thread1.start();
        thread2.start();    // Thread state change to WAIT
        thread1.join();
        thread2.join();
        Assert.assertEquals(1, count);
    }

    @SneakyThrows
    private void lock() {
        lock.lock();
        Thread.sleep(10);
        System.out.println(Thread.currentThread().getName() + ": run " + count++ + " times");
        lock.unlock();
    }

    @SneakyThrows
    private void tryLock() {
        if (lock.tryLock()) {
            Thread.sleep(10);
            try {
                System.out.println(Thread.currentThread().getName() + ": run " + count++ + " times");
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println(Thread.currentThread().getName() + ": get lock fail");
        }
    }

}
